﻿using System;
using FluentMigrator.Runner.Announcers;
using FluentMigrator.Runner.Initialization;
using System.Configuration;
using Budget.Config;

namespace Budget.DataBase
{
    public class BudgetMigrator
    {
        private const string DATABASE = "SqlServer2008";
        private const string MIGRATE_TASK_NAME = "migrate";
        private const string ROLLBACK_TASK_NAME = "rollback";
        private const string ROLLBACK_ALL_TASK_NAME = "rollback:all";

        public static void Main()
        {
            try
            {
                var connection = BudgetConfig.BudgetConnectionString;

                Console.ForegroundColor = ConsoleColor.Green;
                Console.WriteLine("Got ConnectionString: [{0}]", connection);
                Console.WriteLine();

                var loop = true;
                while (loop)
                {
                    string selectedOption;

                    Console.ForegroundColor = ConsoleColor.Cyan;
                    Console.WriteLine("Choose task for migrator:");
                    Console.WriteLine("Press 1 for \"migrate\" task. (Migrate the database to the latest version)");
                    Console.WriteLine("Press 2 for \"rollback\" task. (Migrate the database back one version)");
                    Console.WriteLine("Press 3 for \"rollback:all\" task. (Migrates the database back to original state prior to applying migrations)");
                    Console.WriteLine("Press 4 for \"rollback:toversion\" task. (Migrates the database to the specific version)");
                    Console.WriteLine("Press 5 to exit.");
                    var key = Console.ReadKey();
                    Console.WriteLine();

                    selectedOption = key.KeyChar.ToString();

                    var task = MIGRATE_TASK_NAME;
                    var version = 0;

                    switch (selectedOption)
                    {
                        case "1":
                            break;
                        case "2":
                            task = ROLLBACK_TASK_NAME;
                            break;
                        case "3":
                            task = ROLLBACK_ALL_TASK_NAME;
                            break;
                        case "4":
                            Console.WriteLine("Input number of version for migration:");
                            var versionKey = Console.ReadLine();
                            Console.WriteLine();

                            if (int.TryParse(versionKey, out version))
                            {
                                task = MIGRATE_TASK_NAME;
                            }
                            break;
                        case "5":
                            loop = false;
                            continue;
                    }

                    var runner = CreateContext(DATABASE, connection, task, version);
                    new TaskExecutor(runner).Execute();
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
        }

        public static void Migrate(string database, string connection, string task = MIGRATE_TASK_NAME)
        {
            var runner = CreateContext(database, connection, task);
            new TaskExecutor(runner).Execute();
        }

        private static RunnerContext CreateContext(string database, string connection, string task, int version = 0)
        {
            var announcer = new ConsoleAnnouncer
                                {
                                    ShowElapsedTime = true,
                                    ShowSql = true
                                };
            var runner = new RunnerContext(announcer)
                             {
                                 Database = database,
                                 Connection = connection,
                                 Target = typeof(BudgetMigrator).Assembly.Location,
                                 PreviewOnly = false,
                                 Task = task,
                                 Version = version
                             };
            return runner;
        }
    }
}